/*  CustomTheme v1.1@Xenon_x
    
    Форма для редактирования визуальной схемы сайта.
    На основе глобальный css-переменных:
        --base-bg-color: #dfdfdf;
	    --base-block-bg-color: #ededed;
	    --base-block-border-color: #ff8383;
        --base-block-border-shadow: 0px 0px 20px 1px var(--base-block-border-color);
        --base-font-color: #000000;
        --base-title-color: #d30000;
        --base-font-family: verdana,arial,helvetica;
	    --base-font-size: 10pt;
*/


const fontPickerScriptURI = "/Scripts/SiteCustomTheme/FontPicker.js";
const CTStyleURI = "/Scripts/SiteCustomTheme/style.css?ver=1.1.1";

document.head.insertAdjacentHTML(
	"beforeEnd",
	`
	<link rel='stylesheet' type='text/css' href='https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200'>
	<link rel='stylesheet' type='text/css' href=${CTStyleURI}>
`
);

window.addEventListener("load", async () => {
	let CTCont = document.querySelector(".custom-theme");
	let DOMRoot = document.querySelector(":root");
	let isDown = false;
	let settings = save_load_reset_local_store("load");
	let themeList = save_load_reset_local_store("load", {}, "CustomTheme_themeList");
	
	String.prototype.reverse = function(){ return [...this].reverse().join('') }
	if (!CTCont) {
		console.error(
			"Не найден контейнер для активации расширения. Пример: <div class='custom-theme'></div>"
		);
		return;
	}

	CTCont.insertAdjacentHTML(
		"afterBegin",
		`
        <div class="ct-butt material-symbols-rounded anim-colorama">
            palette
        </div>
    `
	);

	let CTButton = document.querySelector(".custom-theme .ct-butt");
	if (!CTButton) {
		console.error("Кнопка активации расширения на странице отсутствует.");
		return;
	}

	const form_templ = `
        <div class='custom-theme-form'>
            <div class='ctf-title'>
                <span class="ctf-title__reset-butt material-symbols-rounded" title="Сбросить на стандартную">restart_alt</span>
                <span class='ctf-title__close-butt material-symbols-rounded' title="Закрыть">Close</span>
                <h2 class='ctf-title__title'>Настройка визуальной темы</h2>
            </div>
			<div class='ctf-tab-controls'>
				<div class='ctf-tab-control active' data-panel='ctf-tab1'>Активная</div>
				<div class='ctf-tab-control' data-panel='ctf-tab2'>Сохраненные</div>
			</div>
			<section class='ctf-tab active' id='ctf-tab1'>
				<fieldset>
				<label for='icon-style'>Стиль иконки</label>
				<select id='ct-form-icon-style'>
					<option selected value="colorama">Colorama</option>
					<option value="pulse">Pulse</option>
				</select> 
				</fieldset>
				<fieldset>
					<legend>Цветовая схема</legend>
					<div class='ctf-control'><label for='ct-b-bg-c'>Фон сайта</label><div class='ctf-spacer'></div><input name='base-bg-color' id='ct-b-bg-c' type='color'></div>
					<div class='ctf-control'><label for='ct-b-b-bg-c'>Фон блоков</label><div class='ctf-spacer'></div><input name='base-block-bg-color' id='ct-b-b-bg-c' type='color'></div>
					<div class='ctf-control'>
						<label for='ct-b-br-c'>Границы блоков</label>
						<div class='ctf-spacer'></div>
						<input name='base-block-border-shadow' id='ct-b-br-sh' type='checkbox'><label title='Эффект свечения' for='ct-b-br-sh'>Выкл</label>
						<input name='base-block-border-color' id='ct-b-br-c' type='color'>
					</div>
					<div class='ctf-control'><label for='ct-b-f-c'>Текст</label><div class='ctf-spacer'></div><input name='base-font-color' id='ct-b-f-c' type='color'></div>
					<div class='ctf-control'><label for='ct-b-t-c'>Заголовки</label><div class='ctf-spacer'></div><input name='base-title-color' id='ct-b-t-c' type='color'></div>
				</fieldset>
				<fieldset>
				<legend>Текст</legend>
				<div class='ctf-control'><label for='font-picker'>Шрифт</label><div name='base-font-family' id='font-picker'></div></div>
				<div class='ctf-control'><label for='ct-b-f-s'>Размер текста</label><input name='base-font-size' id='ct-b-f-s' type='range' min=5, max=100></div>
				</fieldset>
			</section>
			<section class='ctf-tab' id='ctf-tab2'>
				<fieldset>
					<legend>Темы <span class='ctf-theme-add material-symbols-rounded'>playlist_add</span></legend>
					<div class='ctf-theme-list'>
					</div>
				</fieldset>
			</section>
        </div>
    `;

	CTCont.insertAdjacentHTML("beforeEnd", form_templ);
	await importJS(fontPickerScriptURI);
	let form = document.querySelector(".custom-theme-form");
	let CTFTitle = form.querySelector(".ctf-title");
	let CTFCloseButt = form.querySelector(".ctf-title__close-butt");
	let CTFResetSettings = form.querySelector(".ctf-title__reset-butt");
	let CTFThemes = form.querySelector('.ctf-theme-list');
	let CTFIconStyles = [...form.querySelector('#ct-form-icon-style').options].map(o => "anim-" + o.value);
	let CTActiveTheme = "";
	let themeItem = `
			<div class='ctf-theme-item {active}'>
				<label contenteditable>{theme}</label>
				<div class='ctf-theme-controls'>
					<span class='ctf-theme-control material-symbols-rounded apply'>priority</span>
					<span class='ctf-theme-control material-symbols-rounded sync'>sync</span>
					<span class='ctf-theme-control material-symbols-rounded delete'>Delete</span>
				</div>
			</div>
			`

	CTFTitle.addEventListener(
		"mousedown",
		function (e) {
			isDown = true;
			offset = [form.offsetLeft - e.clientX, form.offsetTop - e.clientY];
		},
		true
	);

	CTFTitle.addEventListener(
		"mouseup",
		function () {
			isDown = false;
		},
		true
	);
	CTFTitle.addEventListener(
		"mousemove",
		function (event) {
			event.preventDefault();
			if (isDown) {
				mousePosition = {
					x: event.clientX,
					y: event.clientY,
				};
				form.style.left = mousePosition.x + offset[0] + "px";
				form.style.top = mousePosition.y + offset[1] + "px";
			}
		},
		true
	);

	//Themes
	CTFThemes.addEventListener('focus', e => {
		//title change analog
		if(e.target.hasAttribute('contentEditable')) {
			e.target.dataset.themeName = e.target.innerText;
		}
	}, true);
	CTFThemes.addEventListener('blur', e => changeContentEditable(e.target), true);
	CTFThemes.addEventListener('addTheme', e => changeContentEditable(e.target), true);
	CTFThemes.closest('.ctf-tab').querySelector('.ctf-theme-add').addEventListener('click', () => {
		let newName = "Новая тема";
		let themes = Object.keys(themeList);
		if(themes.length > 9) { alert('Не больше 10 тем.'); return; }
		if(themes.includes(newName)) {
			let i = 1;
			for(i; themes.includes(`${newName} ${i}`); i++) {}
			newName = `${newName} ${i}`;
		}
		CTFThemes.insertAdjacentHTML('afterBegin', themeItem.replace('{theme}', newName));
		let newTheme = CTFThemes.querySelector(':first-child')
		newTheme.dataset.settings = JSON.stringify(settings);
		newTheme.querySelector('label[contenteditable]').dispatchEvent(new Event('addTheme'));
	});
	CTFThemes.addEventListener('click', e => {
		if(!e.target.classList.contains('ctf-theme-control')) return;
		let themeItem = e.target.closest('.ctf-theme-item');
		let themeName = themeItem.querySelector('label').innerText;
		if(e.target.classList.contains('apply')) {
			settings = themeList[themeName];
			updateView('all');
			CTActiveTheme = themeName;
			fillForm(form);
			// CTFThemes.querySelectorAll('.ctf-theme-item').forEach(themeItem => {
			// 	if(themeItem.querySelector('label').innerText.includes(themeName))
			// 		themeItem.classList.add('active');
			// });
			save_load_reset_local_store("save", settings);
			save_load_reset_local_store('save', themeList, "CustomTheme_themeList");
		}
		else if(e.target.classList.contains('sync')) {
			themeList[themeName] = settings;
			save_load_reset_local_store('save', themeList, "CustomTheme_themeList");
		}
		else if(e.target.classList.contains('delete')) {
			delete themeList[themeName];
			themeItem.remove();
			save_load_reset_local_store('save', themeList, "CustomTheme_themeList");
		}
	});

	form.addEventListener("input", e => changeForm(e, form));
	form.querySelectorAll('.ctf-tab-control').forEach(control => control.addEventListener("click", e => {
		if(e.target.classList.contains('active')) return;
		form.querySelectorAll('.ctf-tab-control').forEach(c=>c.classList.remove('active'));
		form.querySelectorAll('.ctf-tab').forEach(c=>c.classList.remove('active'));
		e.target.classList.add('active');
		form.querySelector(`#${e.target.dataset.panel}`).classList.add('active');
	}));
	CTFCloseButt.addEventListener("click", () => showForm(form));
	CTFResetSettings.addEventListener("click", () => {
		save_load_reset_local_store("reset");
		location.reload();
	});
	CTButton.addEventListener("click", () => showForm(form));
	const fontPicker = new FontPicker(
		"AIzaSyCpTe3oCvzfhnb9dJ1iMqS--_moeVrJrqQ", // Google API key
		"Open Sans", // Default font
		{
			limit: 100,
			scripts: ["cyrillic-ext"],
		}, // Additional options
		(onChange = (font) => {
			let fontSelector = form.querySelector('[name="base-font-family"');
			fontSelector.dispatchEvent(new Event("input", { bubbles: true }));
		})
	);
	initSettings();

	function initSettings() {
		if (!Object.keys(settings).length) return;
		if (settings.buttAnim) {
			let animSelector = form.querySelector("#ct-form-icon-style");
			CTButton.classList.remove.apply(
				CTButton.classList,
				[...animSelector.options].map((o) => "anim-" + o.value)
			);
			CTButton.classList.add(settings.buttAnim);
		}
		for (k in settings) {
			if (k.startsWith("--")) {
				DOMRoot.style.setProperty(k, settings[k]);
			}
		}
		if(Object.keys(themeList)) {
			for ( theme in themeList) {
				if(JSON.stringify(themeList[theme]) == JSON.stringify(settings)) {
					CTActiveTheme = theme;
				}
			}
		}
	}

	function showForm(form) {
		form.classList.toggle("ctf-show");
		if (form.classList.contains("ctf-show")) fillForm(form);
	}

	function fillForm(form) {
		let rootStyle = getComputedStyle(DOMRoot);
		let currButtAnim;
		let animSelector = form.querySelector("#ct-form-icon-style");
		for (c of CTButton.classList) {
			if (c.includes("anim-")) {
				currButtAnim = c.replace("anim-", "");
				break;
			}
		}
		for (o of animSelector.options) if (o.value.includes(currButtAnim)) o.selected = true;
		form.querySelectorAll("[name]").forEach((c) => {
			if (c.getAttribute("name") == "base-block-border-shadow") {
				c.checked = settings.hasOwnProperty("--" + c.getAttribute("name"));
			} else if (c.getAttribute("name") == "base-font-family") {
				try {
					fontPicker.setActiveFont(
						rootStyle.getPropertyValue("--" + c.getAttribute("name")).trim()
					);
				} catch (e) {}
				return;
			}
			let rootVal = rootStyle.getPropertyValue("--" + c.getAttribute("name")).trim();
			c.value = rootVal || c.value;
			if (["number", "range"].includes(c.type)) c.value = parseInt(rootVal);
		});
		if(Object.keys(themeList).length) {
			CTFThemes.innerHTML = '';
			Object.keys(themeList).forEach(theme => {
				let tamplate = themeItem;
				tamplate = tamplate.replace("{theme}", theme);
				tamplate = tamplate.replace("{active}", CTActiveTheme == theme ? 'active' : '');
				CTFThemes.insertAdjacentHTML('beforeEnd', tamplate);
			});
		}
	}

	function changeForm(e, form) {
		if (e.type.includes("mouse")) return;
		// console.log('form changed');
		// console.log(form);
		//console.log(e);
		let rootStyle = getComputedStyle(DOMRoot);
		let animSelector = form.querySelector("#ct-form-icon-style");
		if (e.target.id == "ct-form-icon-style") {
			settings["buttAnim"] = "anim-" + e.target.selectedOptions[0].value;
			updateView('buttAnim');
		} else if (e.target.getAttribute("name") == "base-block-border-shadow") {
			if (e.target.checked) {
				let boxShadow = "0px 0px 15px 1px var(--base-block-border-color)";
				settings[`--base-block-border-shadow`] = boxShadow;
			} else {
				delete settings[`--${e.target.getAttribute("name")}`];
			}
			updateView('--base-block-border-shadow');
		} else if (e.target.getAttribute("name") == "base-font-family") {
			let currFont = fontPicker.getActiveFont().family;
			settings[`--${e.target.getAttribute("name")}`] = currFont;
			updateView('--base-font-family')
		} else if (e.target.getAttribute("name")) {
			settings[`--${e.target.getAttribute("name")}`] = e.target.value + (e.target.getAttribute("name") == "base-font-size" ?  "pt" : '');
			updateView(`--${e.target.getAttribute("name")}`);
		}
		save_load_reset_local_store("save", settings);
	}

	function updateView(option='all') {
		if(!settings) {console.error('[settings] object not exist!'); return;}
		let rootStyle = getComputedStyle(DOMRoot);
		let usedOptions = [
			'buttAnim',
			'--base-block-border-shadow',
			'--base-font-family'
		]
		if(option == "all" || option == "buttAnim") {
			CTButton.classList.remove.apply(
				CTButton.classList,
				CTFIconStyles
			);
			CTButton.classList.add(settings['buttAnim']);
		}
		if(option == 'all' || option == '--base-block-border-shadow') {
			if(settings['--base-block-border-shadow'])
				DOMRoot.style.setProperty("--base-block-border-shadow",
									settings[`--base-block-border-shadow`]);
			else DOMRoot.style.removeProperty("--base-block-border-shadow");
		}
		if((option == 'all' || option == '--base-font-family') && settings["--base-font-family"]) {
			DOMRoot.style.setProperty("--base-font-family",
									settings["--base-font-family"]);
		}
		if(option == 'all' || (option.startsWith('--') && !usedOptions.includes(option))) {
			for(opt in settings) {
				if(!usedOptions.includes(opt)) {
					DOMRoot.style.setProperty(
						opt,
						settings[opt]
					);
				}
			}
		}
	}

	function save_load_reset_local_store(operation, obj = {}, stor = "CustomThemeSettings") {
		let result = false;
		if (operation == "save") {
			localStorage.setItem(stor, JSON.stringify(obj));
			result = true;
		} else if (operation == "load") {
			result = JSON.parse(localStorage.getItem(stor)) || obj;
		} else if (operation == "reset") {
			localStorage.removeItem(stor);
			result = true;
		} else {
			console.warn(`operation[${operation}] not valid.`);
		}
		return result;
	}

	function importJS(uri) {
		return new Promise(function (resolve, reject) {
			const s = document.createElement("script");
			let r = false;
			s.type = "text/javascript";
			s.src = uri;
			s.async = true;
			s.onerror = function (err) {
				reject(err, s);
			};
			s.onload = s.onreadystatechange = function () {
				// console.log(this.readyState); // uncomment this line to see which ready states are called.
				if (!r && (!this.readyState || this.readyState == "complete")) {
					r = true;
					resolve();
				}
			};
			const t = document.getElementsByTagName("script")[0];
			t.parentElement.insertBefore(s, t);
		});
	}

	function changeContentEditable(target) {
		if(target.hasAttribute('contentEditable')) {
			let savedTheme = themeList[target.dataset.themeName];
			let themeName = target.innerText.replaceAll('\n', ' ');
			if(savedTheme) {
				delete themeList[target.dataset.themeName];
				themeList[themeName] = savedTheme;
			} else {
				let currentTheme = settings;
				themeList[themeName] = currentTheme;
			}
			save_load_reset_local_store('save', themeList, "CustomTheme_themeList");
		}
	}
});
